﻿using UnityEngine;
using UnityEngine.UI;
using static CyberU;
using static CyberU.UI;

public class RoundedCorner : MonoBehaviour
{
    [Tooltip("Default corner radius in pixels")]
    public static float defaultRadius = 20f;
    [SerializeField, Range(0, 500)] 
    public float radius = defaultRadius;
    public Material materialInstance;

    public RectTransform rectTransform;
    public Vector2 lastSize;

    private const string SHADER_NAME = "Custom/RoundedCorners";
    private static readonly int CornerRadiusProperty = Shader.PropertyToID("_CornerRadius");
    public void Awake()
    {
        try
        {
            InitializeComponents();
            UpdateMaterial();
        }
        catch (System.Exception e)
        {
            Debug.LogError($"Awake failed: {e}");
        }
    }

    public void InitializeComponents()
    {
        rectTransform = GetComponent<RectTransform>();
        graphic = GetOrAddComponent<Image>(gameObject);
        // Delog(graphic);
    }

    public Image graphic;
    private void Update()
    {
        if (HasSizeChanged())
        {
            UpdateMaterial();
        }
    }

    private bool HasSizeChanged()
    {
        Vector2 currentSize = rectTransform.rect.size;
        if (currentSize != lastSize)
        {
            lastSize = currentSize;
            return true;
        }
        return false;
    }

    public void SetRadius(float newRadius)
    {
        if (Mathf.Approximately(radius, newRadius)) return;
        
        radius = Mathf.Clamp(newRadius, 0f, Mathf.Min(rectTransform.rect.width, rectTransform.rect.height) / 2);
        UpdateMaterial();
    }

    private void UpdateMaterial()
    {
        if (graphic == null || rectTransform == null) return;

        // Get the minimum dimension for normalization
        float minSize = Mathf.Min(rectTransform.rect.width, rectTransform.rect.height);
        if (minSize <= Mathf.Epsilon) return;
        if (materialInstance == null)
        {
            Shader shader = Shader.Find(SHADER_NAME);
            if (shader == null)
            {
                Debug.LogError($"Shader not found: {SHADER_NAME}");
                return;
            }
            materialInstance = new Material(shader);
            graphic.material = materialInstance;
        }

        // Normalize radius to 0-1 range based on smallest dimension
        float normalizedRadius = Mathf.Clamp01(radius / minSize);
        materialInstance.SetFloat(CornerRadiusProperty, normalizedRadius);
    }

    private void OnDestroy()
    {
        // Delog(3);
        if (materialInstance != null)
        {
            if (graphic != null)
            {
                graphic.material = null;
            }
            Destroy(materialInstance);
        }
    }

    private void OnValidate()
    {
        if (!Application.isPlaying && materialInstance != null)
        {
            UpdateMaterial();
        }
    }
}